# -*- coding: latin-1 -*-
#=========================================================================================
from Code.Constantes import *

import os
import codecs

from PyQt4 import QtGui, QtCore

import Code.VarGen as VarGen
import Code.Util as Util
import Code.Tacticas as Tacticas
import Code.AperturasStd as AperturasStd

import Code.QT.Iconos as Iconos
import Code.QT.Controles as Controles
import Code.QT.Colocacion as Colocacion
import Code.QT.QTVarios as QTVarios
import Code.QT.QTUtil2 as QTUtil2
import Code.QT.FormLayout as FormLayout

import Code.QT.WBG_Tree as WBG_Tree
import Code.QT.WBG_Training as WBG_Training


#=========================================================================================
class WN_LB( Controles.ED ) :
    def __init__( self, wNavigator, id ) :
        Controles.ED.__init__( self, wNavigator )
        self.id = id
        self.wNavigator = wNavigator

        # self.soloLectura(True)
        self.si2 = False
        p = wNavigator.palette()
        self.setStyleSheet( "background-color: %s;"%p.color(p.Window).name() )
        self.ponTipoLetra(peso=60,puntos=10)
        self.ponTexto("")
    def mousePressEvent( self, event ) :
        Controles.ED.mousePressEvent( self, event )
        if event.button() == QtCore.Qt.LeftButton :
            self.wNavigator.pulsadoBT( self.id, True, posicion=self.cursorPosition() )

    def mouseReleaseEvent( self, event ) :
        Controles.ED.mouseReleaseEvent( self, event )
        if event.button() == QtCore.Qt.LeftButton :
            self.wNavigator.pulsadoBT( self.id, False, si2=self.si2 )
        self.si2 = False

    def mouseDoubleClickEvent(self, event) :
        self.si2 = True

    def ponTexto( self, txt, maxim=9999 ) :
        Controles.ED.ponTexto( self, txt )
        fm = self.fontMetrics()
        w = fm.boundingRect(txt).width()
        w += 10
        if w > maxim :
            w = maxim
        self.setFixedWidth( w )

class WNavigator( QtGui.QWidget ) :
    def __init__( self, wmoves ) :
        QtGui.QWidget.__init__( self )

        self.wmoves = wmoves
        self.move = None
        self.siWorking = False
        self.historia = None

        # Inicial

        self.bt = WN_LB(self, 1 )
        self.bt.setBackgroundRole(QtGui.QPalette.Window)

        layout = Colocacion.H().control(self.bt).relleno(1).margen(3)
        self.setLayout(layout)

    def pulsadoBT( self, id, siInicio, posicion=None, si2=False ) :
        if siInicio : # se muestra el item y se guarda el item
            if self.historia :
                txt = self.bt.texto()[:posicion]
                numMove = txt.count(" ")+1
                self.siWorking = True
                self.tmpItem = self.historia[numMove].item()
                self.wmoves.tree.setCurrentItem( self.tmpItem )
                self.wmoves.tree.scrollToItem( self.tmpItem )

        else :
            if si2 : # se va a esa posici?n
                self.siWorking = False
                self.wmoves.tree.setCurrentItem( self.tmpItem )
            else : # vuelve a ver el item ultimo
                if self.historia :
                    item = self.historia[-1].item()
                    self.wmoves.tree.setCurrentItem( item )
                    self.wmoves.tree.scrollToItem( item )
                self.siWorking = False

    def ponMove( self, move, texto ) :
        if self.siWorking :
            return
        self.move = move
        self.historia = move.historia()
        while ">" in texto :
            d = texto.find( "<" )
            if d == -1 :
                break
            h = texto.find( ">" )
            texto = texto[:d]+texto[h+1:]
        self.bt.ponTexto(texto,self.wmoves.width()-36)

#=========================================================================================
class WMoves( QtGui.QWidget ) :
    def __init__( self, winBookGuide ) :
        QtGui.QWidget.__init__( self )

        self.winBookGuide = winBookGuide
        self.bookGuide = None # <--setBookGuide
        self.wsummary = None # <--setSummary
        self.infoMove = None # <--setInfoMove

        # Tree
        self.tree = WBG_Tree.TreeMoves( self )

        # ToolBar
        liAccionesWork = (
                            ( _( "Close" ), Iconos.MainMenu(), "tw_terminar" ), None,
                            ( _( "Bookmarks" ), Iconos.Favoritos(), "tw_bookmarks" ),
                        )
        self.tbWork = Controles.TB( self, liAccionesWork, tamIcon = 24 )

        liAccionesGen = (
                            ( _( "Change" ), Iconos.Modificar(), "tg_cambiar" ),
                            ( _( "New" ), Iconos.TutorialesCrear(), "tg_crear" ),
                            ( _( "Copy" ), Iconos.Copiar(), "tg_copiar" ),
                            ( _( "Append" ), Iconos.Mezclar(), "tg_append" ),
                            ( _( "Remove" ), Iconos.Borrar(), "tg_borrar" ),
                            ( _( "Rename" ), Iconos.Rename(), "tg_rename" ),
                            ( _( "Training" ), Iconos.Entrenamiento(), "tg_training" ),
                        )
        self.tbGen = Controles.TB( self, liAccionesGen, tamIcon = 24 )

        # Name
        self.lbName = Controles.LB( "" ).ponWrap().alinCentrado().ponColorFondoN( "white", "grey" ).ponTipoLetra(puntos=12)

        # Navigator
        self.navigator = WNavigator(self)
        self.btInicial = Controles.PB( self, "", self.tw_inicio ).ponIcono( Iconos.MoverInicio() ).anchoFijo(16)
        lyN = Colocacion.H().control(self.btInicial).control(self.navigator).relleno(1).margen(3)

        lyTB = Colocacion.H().control(self.tbWork).relleno(1).control(self.tbGen)

        layout = Colocacion.V().control(self.lbName).otro(lyTB).control(self.tree).otro(lyN).margen(1)

        self.setLayout(layout)

    #--------------------------------------------------------------------------------------------------------------------------------
    def focusInEvent( self, event ) :
        self.winBookGuide.ultFocus = self

    #--------------------------------------------------------------------------------------------------------------------------------
    def actualiza( self ) :
        ultFocus = self.winBookGuide.ultFocus
        if ultFocus == self.wsummary :
            self.wsummary.cambiaInfoMove()
        else :
            item,move = self.tree.moveActual()
            if move is None :
                self.tw_inicio()
            else :
                self.seleccionado(move)

    #--------------------------------------------------------------------------------------------------------------------------------
    def seleccionado(self, move, siSelecciona = False):
        self.infoMove.ponMovimiento( move )
        self.infoMove.modoNormal()
        self.wsummary.actualiza()
        if siSelecciona :
            # self.setFocus()
            # self.tree.setFocus()
            item = move.item()
            self.tree.scrollToItem(item)
            self.tree.setCurrentItem(item)
            item.setExpanded(True)
        self.navigator.ponMove(move,self.infoMove.lbPGN.texto())

    #--------------------------------------------------------------------------------------------------------------------------------
    def showActiveName( self ) :
        active, name = self.bookGuide.dataActiveTable()
        self.lbName.ponTexto(name)

    #--------------------------------------------------------------------------------------------------------------------------------
    def setBookGuide( self, bookGuide ) :
        self.bookGuide = bookGuide
        self.showActiveName()
        self.setToolBar()
        self.tree.clear()
        self.tree.setBookGuide(bookGuide)
        # self.bookGuide.reset()
        self.bookGuide.root.item(self.tree)
        self.compruebaBookmarks()

    #--------------------------------------------------------------------------------------------------------------------------------
    def compruebaBookmarks( self ) :
        self.tbWork.setActionVisible( "tw_bookmarks", len(self.bookGuide.bookmarks)>0 )

    #--------------------------------------------------------------------------------------------------------------------------------
    def ponFenM2inicial( self, fenM2inicial, pvInicial ) :
        self.tree.showChildren( self.bookGuide.root, True )
        if fenM2inicial :
            li = self.bookGuide.getMovesFenM2(fenM2inicial)
            if li :
                msel = li[0]
                for mv in li :
                    if mv.pv() == pvInicial :
                        msel = mv
                        break
                self.seleccionaMove( msel )
                return

        self.tw_inicio()

    #--------------------------------------------------------------------------------------------------------------------------------
    def setSummary(self, wsummary ) :
        self.wsummary = wsummary

    #--------------------------------------------------------------------------------------------------------------------------------
    def setInfoMove(self, infoMove ) :
        self.infoMove = infoMove

    #--------------------------------------------------------------------------------------------------------------------------------
    def setToolBar(self):
        active, dicL = self.bookGuide.getConfiguration()
        wd = len(dicL) > 1
        for key in ( "tg_cambiar", "tg_mezclar", "tg_borrar" ):#, "tg_append" ) :
            self.tbGen.setActionVisible( key, wd )

    #--------------------------------------------------------------------------------------------------------------------------------
    def showChildren( self, unMove ) :
        self.tree.showChildren( unMove, True )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarTB( self ) :
        getattr( self, self.sender().clave )()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_terminar( self ) :
        self.winBookGuide.terminar()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_bookmarks( self ) :
        libm = self.bookGuide.bookmarks
        n = len(libm)
        if n == 0 :
            return
        else :
            menu = QTVarios.LCMenu()

            for mv in libm :
                menu.opcion( mv, mv.mark(), Iconos.PuntoAmarillo())

            menu.separador()
            menu.opcion( "all", "Remove all", Iconos.Delete() )
            resp = menu.lanza()

            if resp is None :
                return

            if resp == "all" :
                li = self.bookGuide.bookmarks[:]
                for mv in li :
                    mv.mark("")
                    self.tree.ponIconoBookmark(mv.item(),"")

                self.compruebaBookmarks()
                return

            mvSel = resp

        self.seleccionaMove( mvSel )

    #--------------------------------------------------------------------------------------------------------------------------------
    def seleccionaMove(self, move):
        li = move.historia()
        for move in li :
            if not move.item() :
                self.showChildren( move.father() )

        self.tree.scrollToItem(li[1].item())
        self.seleccionado(move, True)

    #--------------------------------------------------------------------------------------------------------------------------------
    def tw_inicio( self ) :
        self.seleccionado( self.bookGuide.root, False )
        self.tree.setCurrentItem( None )

    #--------------------------------------------------------------------------------------------------------------------------------
    def getNewName( self, title, previous="" ) :
        name = previous

        while True :
            liGen = [(None,None)]
            liGen.append( ( _( "Name" ) + " :", name ) )

            resultado = FormLayout.fedit( liGen, title=title, parent = self, anchoMinimo = 460, icon = Iconos.TutorialesCrear() )
            if resultado is None :
                return None

            accion, liResp = resultado
            name = liResp[0].strip()
            if not name :
                return None

            active, dicL = self.bookGuide.getConfiguration()
            ok = True
            for k, v in dicL.iteritems() :
                if v.upper() == name.upper() :
                    QTUtil2.mensError(self, _("The name is repeated") )
                    ok = False
                    break
            if ok :
                return name

    # --------------------------------------------------------------------------------------------------------------------------------
    def inicializa( self ) :
        self.tree.clear()
        self.winBookGuide.ultFocus = self
        self.winBookGuide.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_crear( self ) :
        name = self.getNewName(_("New"))
        if name :
            self.bookGuide.newTable(name)
            self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_copiar( self ) :
        name = self.getNewName(_( "Copy" ))
        if name :
            antActive = self.bookGuide.getActiveTable( )
            tableFrom, dicL = self.bookGuide.getConfiguration()
            self.bookGuide.newTable(name)
            tableTo, dicL = self.bookGuide.getConfiguration()
            self.bookGuide.copyTable( tableFrom, tableTo )
            self.bookGuide.setActive(antActive)
            # self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def selectOther( self ) :
        active, dicL = self.bookGuide.getConfiguration()
        menu = QTVarios.LCMenu()

        for k,v in dicL.iteritems() :
            if k != active :
                menu.opcion( (k,v), v, Iconos.PuntoRojo() )
                menu.separador()
        resp = menu.lanza()
        return resp

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_cambiar( self ) :
        resp = self.selectOther()
        if resp is None :
            return
        numTabla,v = resp
        self.bookGuide.grabar()
        self.tree.clear()
        self.bookGuide.setActiveNumTable( numTabla )
        self.bookGuide.reset()
        self.bookGuide.root.item(self.tree)
        self.ponFenM2inicial( self.winBookGuide.fenM2inicial, self.winBookGuide.pvInicial )
        self.winBookGuide.ultFocus = self
        self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_append( self ) :
        active, dicL = self.bookGuide.getConfiguration()
        menu = QTVarios.LCMenu()

        for k,v in dicL.iteritems() :
            if k != active :
                menu.opcion( (k,v), v, Iconos.PuntoVerde() )
        menu.separador()
        menu.opcion( "pgn", _("Import a PGN with variations"), Iconos.PuntoNaranja() )
        menu.separador()
        menu.opcion( "polyglot", _( "Import a polyglot book" ), Iconos.Libros() )
        menu.separador()
        menu1 = menu.submenu( _("Import standard openings" ), Iconos.PuntoAzul() )
        menu1.opcion( "std_all", _("All"), Iconos.PuntoVerde() )
        menu1.separador()
        menu1.opcion( "std_basic", _("Only basic" ), Iconos.PuntoAmarillo() )
        resp = menu.lanza()
        if resp is None :
            return

        if resp == "pgn" :
            self.tg_append_pgn()
        elif resp == "std_all" :
            self.tg_append_std(False)
        elif resp == "std_basic" :
            self.tg_append_std(True)
        elif resp == "polyglot" :
            self.tg_append_polyglot()
        else :
            k,v = resp
            self.bookGuide.mixTable( k, active )
            self.bookGuide.setActive( active )
            self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_append_polyglot(self):
        liGen = [(None,None)]

        config = FormLayout.Fichero( _( "Polyglot book" ), "bin", False, anchoMinimo=280 )
        liGen.append( ( config, "" ) )

        liGen.append( ( None, _("Select a maximum number of moves (plies)<br> to consider from each game") ) )

        liGen.append( ( FormLayout.Spinbox( _("Depth"), 3, 99, 50 ), 30 ) )
        liGen.append( (None,None) )

        liGen.append( ( _("Only white best moves"), False ) )
        liGen.append( (None,None) )

        liGen.append( ( _("Only black best moves"), False ) )
        liGen.append( (None,None) )

        resultado = FormLayout.fedit( liGen, title=_("Import a polyglot book"), parent = self, anchoMinimo = 460, icon = Iconos.PuntoNaranja() )

        if resultado :
            accion, liResp = resultado
            ficheroBIN = liResp[0]
            if ficheroBIN :
                depth = liResp[1]
                whiteBest = liResp[2]
                blackBest = liResp[3]
                # um = QTUtil2.unMomento(self)
                self.bookGuide.grabarPolyglot( self, self.bookGuide.getActiveTable(), ficheroBIN, depth, whiteBest, blackBest )
                # um.final()
                self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_append_pgn(self):
        liGen = [(None,None)]

        config = FormLayout.Fichero( _( "File to import" ), "%s (*.pgn)"%_("PGN Format"), False, anchoMinimo=280 )
        liGen.append( ( config, "" ) )

        liGen.append( ( None, _("Select a maximum number of moves (plies)<br> to consider from each game") ) )

        liGen.append( ( FormLayout.Spinbox( _("Depth"), 3, 999, 50 ), 30 ) )
        liGen.append( (None,None) )

        resultado = FormLayout.fedit( liGen, title=_("Import a PGN"), parent = self, anchoMinimo = 460, icon = Iconos.PuntoNaranja() )

        if resultado :
            accion, liResp = resultado
            ficheroPGN = liResp[0]
            if ficheroPGN :
                depth = liResp[1]
                self.bookGuide.grabarPGN( self, self.bookGuide.getActiveTable(), ficheroPGN, depth )
                self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_append_std(self, siBasic):
        activeTable = self.bookGuide.getActiveTable()

        self.bookGuide.grabarSTD( self, activeTable, siBasic=siBasic)
        self.inicializa()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_borrar(self):
        resp = self.selectOther()
        if resp is None :
            return

        k,v = resp
        if QTUtil2.pregunta( self, _X(_( "Delete %1 ?" ), v ) ) :
            self.bookGuide.remove( k )

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_rename( self ) :
        active, name = self.bookGuide.dataActiveTable()
        name = self.getNewName(_("Rename"), name )
        if name :
            self.bookGuide.rename(active,name)
            self.showActiveName()

    #--------------------------------------------------------------------------------------------------------------------------------
    def tg_training( self ) :

        w = WBG_Training.WTraining( self, self.tree.dicValoracion, self.tree.dicVentaja )
        w.exec_()
        if not w.siAceptado :
            return
        dic = w.resultado()
        siBlancas = dic["SIWHITE"]
        tactica = Tacticas.BaseTactica()
        menuname = dic["NAME"]
        depth = dic["DEPTH"]
        reValW, reVenW = dic["WHITE"]
        reValB, reVenB = dic["BLACK"]
        dicVal = { True:reValW, False:reValB }
        dicVen = { True:reVenW, False:reVenB }
        siAddOpening = dic["ADDSTD"]
        if siAddOpening :
            listaAperturasStd = AperturasStd.ListaAperturasStd(VarGen.configuracion,False,False)
        tactica.SHOWTEXT = [0 if siAddOpening else 1,]

        # Leemos todas las lineas=listas de movimientos
        liT = self.bookGuide.allLines()

        # Se calcula el nombre de la carpeta
        active, name = self.bookGuide.dataActiveTable()
        restDir = Util.validNomFichero(name)
        nomDir = os.path.join(VarGen.configuracion.dirPersonalTraining,"Tactics",restDir)
        nomIni = os.path.join( nomDir, "Config.ini" )
        if os.path.isfile(nomIni) :
            dic = Util.ini8dic( nomIni )
            n = 1
            while True :
                if "TACTIC%d"%n in dic :
                    if "MENU" in dic["TACTIC%d"%n] :
                        if dic["TACTIC%d"%n]["MENU"].upper() == menuname.upper() :
                            break
                    else :
                        break
                    n += 1
                else :
                    break
            nomTactic = "TACTIC%d"%n
        else :
            nomDirTac = os.path.join(VarGen.configuracion.dirPersonalTraining,"Tactics")
            Util.creaCarpeta(nomDirTac)
            Util.creaCarpeta(nomDir)
            nomTactic = "TACTIC1"
            dic = {}
        nomFNS = os.path.join( nomDir, nomTactic + ".fns" )

        # Se crea el fichero con los puzzles
        f = codecs.open( nomFNS, "w", "utf-8",'ignore' )
        setPr = set()
        for nline, liMV in enumerate(liT) :
            if not siBlancas :
                liMV = liMV[2:]
            else :
                liMV = liMV[1:]
            if not liMV :
                continue

            fenBase = liMV[0].fenBase()

            numJG = 1
            pgn = ""
            if not siBlancas :
                pgn += "%d..."%numJG
                numJG += 1
            colorAct = siBlancas
            if len(liMV) > depth :
                liMV=liMV[:depth]

            for mv in liMV :
                mas = ""

                if mv.adv() in dicVen[colorAct] or \
                    mv.nag() in dicVal[colorAct] :
                    continue

                if colorAct == siBlancas :
                    liBrothers = mv.brothers()
                    for mv1 in liBrothers :
                        mas += "(%s)"%mv1.pgn()

                if colorAct :
                    pgn += " %d."%numJG
                    numJG += 1
                pgn += " " + mv.pgn()
                if mas :
                    pgn += " "+mas
                colorAct = not colorAct

            k = fenBase+pgn

            if k not in setPr :
                txt = ""
                if siAddOpening :
                    opening = listaAperturasStd.asignaAperturaListaMoves( liMV )
                    if opening :
                        txt += "%s: %s<br>"%(_("Opening"),opening)
                txt += mv.comment()

                f.write( "%s|%s|%s\n"%(fenBase,txt,pgn))
                setPr.add(k)
        f.close()

        #Se crea el fichero de control
        dic[nomTactic] = d = {}
        d["MENU"] = menuname
        d["FILESW"] = "%s.fns:100"%nomTactic

        d["PUZZLES"] = str(tactica.PUZZLES)
        for field in ("JUMPS", "REPEAT", "PENALIZATION", "SHOWTEXT" ) :
            d[field] = tactica.comas2texto(field)

        Util.dic8ini( nomIni, dic )

        VarGen.procesador.entrenamientos.rehaz()

        QTUtil2.mensaje( self,  _X(_("Tactic training %1 created."), menuname) + "<br>"+\
                                _X(_( "You can access this training from menu Trainings-Learn tactics by repetition-%1"),name) )

